﻿using ServiceCore.DbContext;
using ServiceCore.Entity.Arg;
using ServiceCore.Entity.Const;
using ServiceCore.Entity.Const.Record;
using ServiceCore.Entity.Model;
using ServiceCore.Utility.Extension;
using System.Text;

namespace ServiceCore.Service
{
    /// <summary>
    /// 文字处理
    /// </summary>
    public partial class TextParseService : SqlsugarServices<RecordInfo>
    {
        /// <summary>
        /// 参数
        /// </summary>
        /// <param name="arg"></param>
        public void Text_Parse_Text_Arg(ArgTextParse arg)
        {
            if (arg == null)
            {
                arg = new ArgTextParse();
                arg.ErrorMsg = "参数不能为空";
                return;
            }
            if (string.IsNullOrEmpty(arg.Text))
            {
                arg.ErrorMsg = "解析内容不能为空";
                return;
            }
            if (string.IsNullOrEmpty(arg.SiteId))
            {
                arg.ErrorMsg = "分组id不能为空";
                return;
            }

            arg.lstTagType = this.Context.Queryable<TagTypeInfo>().ToList();
            if (arg.lstTagType.Any() == false)
            {
                arg.ErrorMsg = "无标签类型信息，请先创建标签类型";
                return;
            }
            arg.lstTagTypeName = arg.lstTagType.Select(x => x.Name).ToList();

            arg.lstTag = this.Context.Queryable<TagInfo, TagTypeInfo>((a, b) => a.TagTypeId == b.Id)
                .Select((a, b) => new TagInfo()
                {
                    Id = a.Id,
                    Name = a.Name,
                    TagTypeId = b.Id,
                    TagTypeName = b.Name
                })
                .ToList();
            if (arg.lstTag.Any() == false)
            {
                arg.ErrorMsg = "无标签信息，请先创建标签";
                return;
            }
        }

        /// <summary>
        /// 文字转行
        /// </summary>
        /// <param name="arg"></param>
        public void Text_Parse_Text_Lines(ArgTextParse arg)
        {
            if (string.IsNullOrEmpty(arg.ErrorMsg) == false)
                return;
            if (string.IsNullOrEmpty(arg.Text))
                return;

            string normalized = arg.Text.Replace("\r\n", "\n").Replace("\r", "\n");
            var isRemoveEmpty = true; //是否移除空行
            var options = isRemoveEmpty ? StringSplitOptions.RemoveEmptyEntries : StringSplitOptions.None;
            arg.Lines = normalized.Split(new[] { '\n' }, options).ToList();
            if (arg.Lines.Any() == false)
                return;

            for (int i = arg.Lines.Count - 1; i >= 0; i--)
            {
                arg.Lines[i] = arg.Lines[i].TrimStart();
                arg.Lines[i] = arg.Lines[i].TrimEnd();
                if (string.IsNullOrEmpty(arg.Lines[i]))
                    arg.Lines.RemoveAt(i);
            }
        }

        ///// <summary>
        ///// 移动到上一行（合计单独一行移到上行）
        ///// </summary>
        ///// <param name="arg"></param>
        //public void Text_Parse_Text_RemoveUpLines(ArgTextParse arg)
        //{
        //    if (string.IsNullOrEmpty(arg.ErrorMsg) == false)
        //        return;
        //    if (arg.Lines.Any() == false)
        //        return;

        //    var lstSpecial = new List<string>() { "共" };
        //    var lstChar = new List<string>() { ",", "/" };
        //    var temp = string.Empty;
        //    for (int i = arg.Lines.Count - 1; i >= 1; i--)
        //    {
        //        temp = string.Empty;
        //        foreach (var special in lstSpecial)
        //        {
        //            if (arg.Lines[i].IndexOf(special) == 0)
        //            {
        //                temp = arg.Lines[i];
        //                break;
        //            }
        //        }

        //        //特殊处理
        //        if (string.IsNullOrEmpty(temp))
        //        {
        //            /*14,03.15,23,24,25,29,32,39,45,49,
        //            11,12,21,35,44各十共160

        //            15/30
        //            04/5，共155
        //             */
        //            foreach (var special in lstChar)
        //            {
        //                if (arg.Lines[i - 1].Contains(special) && arg.Lines[i - 1].Replace(special, "").Replace(".", "").IsAllNumeric())
        //                {
        //                    temp = " " + arg.Lines[i];
        //                    break;
        //                }
        //            }
        //        }

        //        if (string.IsNullOrWhiteSpace(temp) == false)
        //        {
        //            arg.Lines[i - 1] = arg.Lines[i - 1] + temp;
        //            arg.Lines.RemoveAt(i);
        //        }
        //    }
        //}

        /// <summary>
        /// 移动到上一行（合计单独一行移到上行）
        /// </summary>
        /// <param name="arg"></param>
        public void Text_Parse_Text_RemoveUpLines(ArgTextParse arg)
        {
            if (string.IsNullOrEmpty(arg.ErrorMsg) == false)
                return;
            if (arg.Lines.Any() == false)
                return;

            var temp = string.Empty;
            for (int i = arg.Lines.Count - 1; i >= 1; i--)
            {
                if (arg.Lines[i].IndexOf("共") == 0)
                {
                    arg.Lines[i - 1] = arg.Lines[i - 1] + temp;
                    arg.Lines.RemoveAt(i);
                }
            }

            Text_Parse_Text_RemoveUpLines_Fro(arg, arg.Lines.Count - 1); 
        }

        public void Text_Parse_Text_RemoveUpLines_Fro(ArgTextParse arg, int idx)
        {
            if (idx < 1)
                return;

            var temp = string.Empty;
            int maxIdx = 0;
            for (int i = idx; i >= 1; i--)
            {
                if (arg.Lines[i].Contains("共") == false)
                    continue;

                maxIdx = -1;
                for (int j = i - 1; j >= 0; j--)
                {
                    if (Text_Parse_Text_RemoveUpLines_IsNumberLine(arg.Lines, j) == false)
                        break;
                    maxIdx = j;
                }
                if (maxIdx == -1)
                    continue;

                temp = string.Empty;
                for (int j = i; j > maxIdx; j--)
                {
                    temp = arg.Lines[j] +" " + temp;
                    arg.Lines.RemoveAt(j);
                } 
                arg.Lines[maxIdx] = arg.Lines[maxIdx]+ " " +temp;

                Text_Parse_Text_RemoveUpLines_Fro(arg, maxIdx - 1);
                break;
            }
        }

        public bool Text_Parse_Text_RemoveUpLines_IsNumberLine(List<string> lines, int idx)
        { 
            var str = lines[idx].GetTxtReplaceNumeric().Replace(",", "");
            return str.IsAllNumeric();
        }

        /// <summary>
        /// 合并行
        /// </summary>
        /// <param name="arg"></param>
        public void Text_Parse_Text_RemoveUpLines_Merge(ArgTextParse arg)
        {
            /*
                12-13-17+16+14
                22-23-27-26-24-
                32-33-37-36-34-
                42-43-47-46-44一个数各10块共200总计200+50+200+120+200+25+200=995
             */
            if (string.IsNullOrEmpty(arg.ErrorMsg) == false)
                return;
            if (arg.Datas.Any() == false)
                return;

            Dictionary<int, int> mergeDic = new Dictionary<int, int>();
            var idx = -1;
            for (int i = arg.Datas.Count - 1; i >= 1; i--)
            {
                if (arg.Datas[i].IsTotalLine)
                {
                    idx = i;
                    while (idx >= 0)
                    {
                        idx = i - 1;
                        if (arg.Datas[idx].IsNumberLine == false)
                            break;
                    }
                    if (i - idx >= 2)
                    {
                        mergeDic.Add(i, idx);
                    }
                }
            }
            if (mergeDic.Any() == false)
                return;

            var temp = string.Empty;
            foreach (var key in mergeDic.Keys)
            {
                temp = string.Empty;
                for (int i = key; i > idx; i--)
                {
                    temp = arg.Datas[i] + temp;
                    arg.Datas.RemoveAt(i);
                }
            }
        }
        //        //特殊处理
        //                if (string.IsNullOrEmpty(temp))
        //                {
        //                    /*14,03.15,23,24,25,29,32,39,45,49,
        //                    11,12,21,35,44各十共160

        //                    15/30
        //04/5，               共155
        //                     */
        //                    foreach (var special in lstChar)
        //                    {
        //                        line = arg.Lines[i - 1].Replace(special, "");
        //    }
        //                    if (line.IsAllNumeric())
        //                    {
        //                        temp = " " + arg.Lines[i];
        //                        break;
        //                    }
        //                }


        /// <summary>
        /// 标点符号
        /// </summary>
        /// <param name="arg"></param>
        public void Text_Parse_Text_Punctuate(ArgTextParse arg)
        {
            if (string.IsNullOrEmpty(arg.ErrorMsg) == false)
                return;
            if (arg.Lines.Any() == false)
                return;

            Dictionary<string, string> dicPunctuate = new Dictionary<string, string>()
            {
                { "，", "," }, { "-", "," } , { "   ", " " }, { "：", "," },
                { "各各各", "各" }, { "各各", "各" }, { "各数", "各" }, { "各号", "各" }, { "各打", "各" },{ "各肖", "各" } ,{ "个数", "各" } ,
                { "每各", "各" }, { "个号", "各" }, { "每个号", "各" },{ "每各号", "各" }, { "各字", "各" }, { "每个数字", "各"}, { "各数：", "各"},
                { "一个数", "各" }, { "1个数", "各" }, { "每个数", "各" }, { "每号各", "各" }, { "每号", "各" } ,{ "各 ", "各" }  ,{ "各买", "各" },{ "每米", "各" },
                { "一各", "各" } ,{ "一各号", "各" } , { "一个号", "各" }, { "每各字", "各" }, { "每个字", "各" } ,{ "各,", "各" },
                { "打打打", "打" }, { "打打", "打" }, { "号特", "打" }, { "买", "打" }, { "报", "打" },
                { "合计,", "共"}, { "合计", "共"}  , { "共计", "共"}, { "总计", "共"},{ "总", "共"},{ "一共", "共"},
                { "¥", "" } ,{ "搞", "" } ,{ "奥", "澳" },{ "新澳", "澳" }
            };
            var idx = -1;
            var temp = string.Empty;
            for (int i = 0; i < arg.Lines.Count; i++)
            {
                foreach (var key in dicPunctuate.Keys)
                {
                    arg.Lines[i] = arg.Lines[i].Replace(key, dicPunctuate[key]);
                }

                temp = string.Empty;
                //特殊处理：
                //个转各：08,44,10,46,02,38,11,47,12,48,个5米。【失败原因：获取金额失败】
                if (arg.Lines[i].Contains("个") && arg.Lines[i].Contains("各") == false)
                    arg.Lines[i] = arg.Lines[i].Replace("个", "各");
                //11：30的【失败原因：获取金额失败】
                else if (arg.Lines[i].Contains("："))
                {
                    if (arg.Lines[i].Split('：')[0].IsHaveNumeric() && arg.Lines[i].Contains("打") == false)
                        arg.Lines[i] = arg.Lines[i].Replace("：", "打");
                }
                //计：
                else if (arg.Lines[i].StartsWith("计："))
                    arg.Lines[i] = arg.Lines[i].Replace("计：", "共");
                //46（20斤）
                else if (arg.Lines[i].Contains("（") && arg.Lines[i].Contains("）"))
                    arg.Lines[i] = arg.Lines[i].Replace("）", "").Replace("（", ",");
                else if (arg.Lines[i].Contains("（") && arg.Lines[i].Contains("）"))
                    arg.Lines[i] = arg.Lines[i].Replace("）", "").Replace("（", ",");

                //36—50米
                idx = arg.Lines[i].IndexOf("—");
                if (idx > 0)
                {
                    if (idx == arg.Lines[i].LastIndexOf("—"))
                        arg.Lines[i] = arg.Lines[i].Replace("—", "打");
                }
                //1百
                idx = arg.Lines[i].IndexOf("百");
                if (idx > 0)
                {
                    if (arg.Lines[i].Substring(idx - 1, 1).IsAllNumeric())
                    {
                        if (arg.Lines[i].Contains("包") == false && arg.lstTagTypeName.Any(n => arg.Lines[i].Contains(n)))
                            temp = "包";
                        arg.Lines[i] = arg.Lines[i].Replace("1百", temp + "100");
                        arg.Lines[i] = arg.Lines[i].Replace("2百", temp + "200");
                        arg.Lines[i] = arg.Lines[i].Replace("3百", temp + "300");
                        arg.Lines[i] = arg.Lines[i].Replace("4百", temp + "400");
                        arg.Lines[i] = arg.Lines[i].Replace("5百", temp + "500");
                        arg.Lines[i] = arg.Lines[i].Replace("6百", temp + "600");
                        arg.Lines[i] = arg.Lines[i].Replace("7百", temp + "700");
                        arg.Lines[i] = arg.Lines[i].Replace("8百", temp + "800");
                        arg.Lines[i] = arg.Lines[i].Replace("9百", temp + "900");
                    }
                    else
                    {
                        arg.Lines[i] = arg.Lines[i].Replace("两百", temp + "200");
                    }                   
                }
            }
        }

        /// <summary>
        /// 删除非数字行
        /// </summary>
        /// <param name="arg"></param>
        public void Text_Parse_Text_RemoveNoNumeric(ArgTextParse arg)
        {
            if (string.IsNullOrEmpty(arg.ErrorMsg) == false)
                return;
            if (arg.Lines.Any() == false)
                return;
            if (arg.Lines.Any(x => arg.lstTagTypeName.Contains(x.ToString())) == false)
                return;

            for (int i = arg.Lines.Count - 1; i >= 0; i--)
            {
                if (arg.Lines[i].IsHaveNumeric() == false)
                    arg.Lines.RemoveAt(i);
            }
        }

        /// <summary>
        /// 删除作者（如作者名称包含数字处理）
        /// </summary>
        /// <param name="arg"></param>
        public void Text_Parse_Text_RemoveAuthor(ArgTextParse arg)
        {
            if (string.IsNullOrEmpty(arg.ErrorMsg) == false)
                return;
            if (arg.Lines.Any() == false)
                return;

            var group = arg.Lines.GroupBy(s => s)
                        .Where(g => g.Count() >= 3)
                        .Select(g => g.Key)
                        .ToList();
            if (group.Any() == false)
                return;
            group = group.Where(x => x.Contains(":")).ToList();
            if (group.Any() == false)
                return;

            for (int i = arg.Lines.Count - 1; i >= 0; i--)
            {
                if (group.Contains(arg.Lines[i]))
                    arg.Lines.RemoveAt(i);
            }
        }

        /// <summary>
        /// 删除发送人
        /// </summary>
        /// <param name="arg"></param>
        public void Text_Parse_Text_RemoveMemberText(ArgTextParse arg)
        {
            if (string.IsNullOrEmpty(arg.ErrorMsg) == false)
                return;
            if (arg.Lines.Any() == false)
                return;

            for (int i = arg.Lines.Count - 1; i >= 0; i--)
            {
                if (arg.Lines[i].IsHaveNumeric() == false)
                    arg.Lines.RemoveAt(i);
            }
        }

        /// <summary>
        /// 中文转阿拉伯数字
        /// </summary>
        /// <param name="arg"></param>
        public void Text_Parse_Text_ChineseToNumber(ArgTextParse arg)
        {
            if (string.IsNullOrEmpty(arg.ErrorMsg) == false)
                return;
            if (arg.Datas.Any() == false)
                return;

            var lstChar = new List<string>() { ",", ".", "-", "/", " ", " " };
            var lstTxt = new List<string>();
            foreach (var item in arg.Datas)
            {
                if (item.SourceProcess.HasChineseNumber() == false)
                    continue;

                if (item.ParsemChildMode == ParsemChildMode.ParsemChildMode_Tag_General)
                {
                    if (item.SourceProcess.Substring(0, 1).IsAllNumeric())
                    {
                        lstTxt = item.SourceProcess.Split('共').ToList();
                        if (lstTxt.Count > 1)
                            item.SourceProcess = lstTxt[0].LastNumberValueEndAddTxt("打") + "共" + lstTxt[1];
                        else
                        {
                            item.SourceProcess = item.SourceProcess.LastNumberValueEndAddTxt("打"); //33二十块
                            item.SourceProcess = item.SourceProcess.Replace("打  ", "打").Replace("打 ", "打").Replace("打 ", "打");//33 10元
                        }
                    }
                }

                item.SourceProcess = HighPerformanceChineseParser.ParseNumbersFast(item.SourceProcess, " ");
            }
        }


        /// <summary>
        /// 记录错误日志
        /// </summary>
        /// <param name="arg"></param>
        public void Text_Parse_Text_Log_Error(ArgTextParse arg)
        {
            if (arg.Datas.Any() == false)
                return;
            var errors = arg.Datas.Where(x => x.Result == ParsemResult.ParsemResult_Fail && x.ResultTip != NoTakeName).ToList();
            if (errors.Any() == false)
                return;

            StringBuilder content = new StringBuilder();
            content.AppendLine("入参：" + arg.Text);
            errors.ForEach(x => { content.AppendLine($"来源：{x.Source}【失败原因：{x.ResultTip}】"); });
            content.ToString().LogWriteService(LogServiceCore.LogServiceCore_Error);
        }
    }
}
